home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
142_01
/
crcbuild.asm
< prev
next >
Wrap
Assembly Source File
|
1985-03-09
|
14KB
|
695 lines
;
; CRCBUILD.ASM version 1.0
; by John L. Raff WB2MDG/KAPP8107
; (built 830408FR)
;
;---> NOTE: MUST BE ASSEMBLED BY MAC <----
;
;CRCBUILD is a program to build a CP/M file in SIG/M
;-CATALOG format and print
;a CYCLIC-REDUNDANCY-CHECK number based on the
;CCITT standard polynominal:
; X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
;
;Define true and false
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
;Conditional assembly switches
;
STDCPM EQU TRUE ;TRUE IS STANDARD CP/M
ALTCPM EQU FALSE ;TRUE IS H8 OR TRS-80
NOSYS EQU FALSE ;TRUE IF SYS FILES NOT WANTED
;
;System equates
;
BASE SET 0
IF ALTCPM
BASE SET 4200H
ENDIF ;ALTCPM
;
;Define write buffer size (presently set for 8k)
;
BSIZE EQU 8*1024 ;DISK WRITE BUFFER SIZE
;
;BDOS equates
;
RDCON EQU 1
WRCON EQU 2
PRINT EQU 9
READCONSOLE EQU 10 ;Read console buffer
CSTAT EQU 11
OPEN EQU 15
SRCHF EQU 17
SRCHN EQU 18
READ EQU 20
STDMA EQU 26
BDOS EQU BASE+5
FCB EQU BASE+5CH
FCBEXT EQU FCB+12
FCBRNO EQU FCB+32
FCB2 EQU BASE+6CH
STRLMT EQU 80 ;STRING LENGTH LIMIT
;
;Program starts here
;
ORG BASE+100H
;
MACLIB SEQIO ;DEFINE MACRO LIBRARY USED
CRCBUILD:
JMP BEGIN ;Jump around identification & alternate file name
DB 'CRCBUILD.COM 1.0 830408fr',0
;
BEGIN:
XRA A
STA NAMQUAN ;Zero the quantity of files read
LXI H,0 ;GET STACK...
DAD SP ;POINTER SO WE CAN..
SHLD STACK ;SAVE IT
LXI SP,STACK ;INITIALIZE LOCAL STACK
BGN2:
CALL CRLF ;TURN UP A NEW LINE
CALL ILPRT ;Print the heading
DB 'CRCBUILD Ver 1.0 830224TH',CR,LF
DB 'CTL-S pauses, CTL-C aborts',CR,LF,0
LDA FCB+1
CPI ' ' ;SEE IF NAME THERE
JNZ BEGIN2 ;YES, CONTINUE
LXI D,FCB+2 ;Put total directory pattern
LXI H,FCB+1 ;in FCB
MVI M,'?' ;All "?"
LXI B,10 ;4 characters
CALL MOVER ;MOVE IT
JMP BEGIN2 ;Go get um
;
THRNUM?: ;Check for three ascii numbers
CALL TWONUM?
RNZ ;Return if not numbers
CALL NUM?
RZ ;Return if a number
CPI '.' ;Check for a period
RNZ ;Return if not a period
DCX H ;Otherwise back up one character
DCR B ;And one count
CMP A ;Set zero flag
RET
;
TWONUM?:
CALL NUM?
RNZ
NUM?:
MOV A,M ;Get the character
INX H ;For next character
INR B ;Increment for next count
CPI '0' ;Is it less than 0
JC NUMNOT ;Branch if it is
CPI '9'+1 ;Is it greater than 9?
JNC NUMNOT
CMP A ;Set zero flag
RET
NUMNOT:
CPI '0' ;Should not be equal, reset zero flag
RET
;
BEG2NG:
CALL ILPRT
DB CR,LF,'Incorrect characters',CR,LF,0
;
BEGIN2:
CALL ILPRT
DB 'Enter -CATALOG.xxx number (three digits) -',0
LXI D,STR4 ;Point to string 4
MVI A,5 ;Indicate size of buffer
STAX D
MVI C,READCONSOLE ;Read console buffer
CALL BDOS ;Go get the string
LXI H,STR4+1 ;Point to quantity characters entered
MOV C,M ;Get the count
MVI A,3 ;Check for three characters
CMP C ;In buffer
JNZ BEG2NG ;Branch if not 3 characters
MVI B,0 ;Zero counter
INX H ;Point to first character
BEG2A:
CALL NUM? ;Is it a decimal number?
JNZ BEG2NG ;Branch if not a decimal number
MOV A,B ;Check quantity of characters
CPI 3
JNZ BEG2A ;Branch if not end of characters yet
MVI M,0 ;Ensure termination of string
LXI H,STR4+2 ;Copy number into file string
LXI D,FNAME1
LXI B,3 ;Count
CALL MOVER
MVI A,'F' ;Indicate write file open
STA FFLAG
;
;'Declare' FCB for output file
;(temporarily named -CATALOG.$$$)
;
FILE OUTFILE,CATALOG,,-CATALOG,$$$,BSIZE
;
AGAIN: LXI SP,STACK ;RE-INIT STACK POINTER
MVI A,0 ;Indicate in building phase
STA WHICH ;Save flag
CALL MFNAME ;SEARCH FOR NAMES
JNC NAMTST ;ANOTHER FOUND, PRINT NAME
AGN2:
LDA MFFLG2 ;NOTHING FOUND, CHECK...
ORA A ;... NAME FOUND FLAG
JZ DONE ;AT LEAST ONE WAS FOUND
CALL ABEXIT ;PRINT MSG, THEN EXIT
DB '++FILE NOT FOUND++$'
;
DONE: ;Close -CATALOG.$$$
LXI H,FNAME1
LXI D,DONEX
LXI B,3
CALL MOVER
CALL ILPRT
DB CR,LF,'SIG-M Library -CATALOG Volume Number-'
DONEX:
DB 'NNN, ',0
DONEY:
LDA NAMQUAN
CALL SHWDC
CALL ILPRT
DB ' Files cataloged.',CR,LF,0
;
FINIS CATALOG
;
LXI H,STR4+2 ;Point to beginning of string
LXI D,FCBFINAL+9 ;Location of Name TYPE
LXI B,3 ;Quantity to move
CALL MOVER
;
;Build FCB for final name of -CATALOG.nnn
;
FILE SETFILE, FINAL,,-CATALOG,NNN
;
; Erase any existing old file
;
ERASE FINAL
;
; Rename -CATALOG.$$$ to -CATALOG.NNN
RENAME FINAL,CATALOG
;
;Now exit to CP/M
DONE2:
CALL MSGEXIT ;PRINT DONE, THEN EXIT
DB CR,LF,'DONE$'
;
;Test for names to ignore
;
NAMTST: IF NOSYS
LDA FCB+10 ;GET SYS ATTRIBUTE
ANI 80H ;IS IT SYS?
JNZ AGAIN ;YES, IGNORE THIS FILE
ENDIF ;NOSYS
;
;Ignore files with .$$$ filetype (they are usually
;zero-length and clutter up our display. We also
;want to ignore our own CRCKLIST.$$$ temporary file).
;
LXI H,FCB+9 ;POINT TO FILETYPE IN FCB
PUSH H ;May need pointer for BAD check
CALL TSTBAD ;CHECK FOR .$$$ FILES
JZ AGAIN ;IF ZERO FLAG, IGNORE THEM
POP H ;Restore pointer
CALL BADTYP ;Check for .BAD files
JZ AGAIN ;Branch if it is
;
NAMTS2:
CALL ILPRT ;PRINT:
DB CR,LF
FNAME1:
DB 'NNN.',0
;
LDA NAMQUAN ;Get quantity of name
INR A ;Increment count
STA NAMQUAN
CALL SHWDC ;Show the count
;
;Move 8 characters from FCB+1 to FNAME
;
LXI H,FCB+1
LXI D,FNAME
LXI B,8
CALL MOVER
;Move 3 characters from FCB+9 to FNAME+9
LXI H,FCB+9
LXI D,FNAME+9
LXI B,3
CALL MOVER
;Now print filename.type
CALL ILPRT
DB ' '
FNAME:
DB 'XXXXXXXX.XXX ',0
FNAME2:
CALL OPN ;Open file and build CRC
JZ AGAIN ;Branch if bad open or read
JMP ABEXT2 ;Otherwise get out
;
;Open the file
;
OPN:
LXI D,FCB
MVI C,OPEN
CALL BDOS
INR A
JNZ RDINIT
CALL ILPRT
DB '++Open Failed++',0
JMP BADRET ;Indicate Bad open
;
;Initialize CRC to zero and set Bufad to cause initial read
;
RDINIT:
LXI H,0
SHLD REM ;Init remainder to zero
SHLD QUANEK ;Quantity of eighth k
LXI H,BASE+100H
SHLD BUFAD ;Init buffer address
;
;This is the read loop
;
READIT:
LHLD BUFAD
MOV A,H ;Time to read?
CPI BASE SHR 8 ;End of buffer?
JZ NORD
MVI C,CSTAT
CALL BDOS ;Chck for operator abort
ORA A
JZ READ2 ;Branch if nothing from operator
MVI C,RDCON
CALL BDOS ;Get character from operator
CPI 'C'-40h ;Control C?
JZ ABEXT2 ;Branch if yes, exit
;
READ2:
LXI D,FCB
MVI C,READ ;Read another sector of file
CALL BDOS
ORA A ;Check return code
JNZ FINISH ;Error or EOF
LHLD QUANEK ;Get quantity of eighth K
INX H ;Add 1
SHLD QUANEK ;Put back
LXI H,BASE+80H ;Bufer location
;
NORD:
MOV A,M ;Get file character
STA MESS ;Save for DIVP
INX H
SHLD BUFAD ;Update buffer address
CALL DIVP ;Calculate new CRC
JMP READIT ;GO READ MORE CHARACTERS
;
FINISH: CPI 1 ;NORMAL END-OF-FILE?
JNZ FILERR ;NO, IT WAS A READ ERROR
LHLD QUANEK ;Get quantity of eighth K
LXI B,7
DAD B ;Round up to next K
DAD H ;Turn into full K
DAD H ;In "H" register
DAD H
DAD H
DAD H
MOV A,H
CALL SHWDEC ;Show Number of K
CALL ILPRT
DB 'K ',0
LDA REM+1 ;GET MSP OF CRC
CALL HEXO ;PRINT IT
MVI A,' '
CALL TYPE ;TYPE A SPACE
LDA REM ;GET LSP OF CRC
CALL HEXO ;PRINT IT
GOODRET:
XRA A
RET ;Return to caller with zero flag set
;
FILERR:
CALL ILPRT ;Print the message and return
DB TAB,TAB,'++FILE READ ERROR++',CR,LF,0
BADRET: ;General bad return location
XRA A ;Set zero flag
INR A ;reset zero flag
RET ;Return to caller
;
;---------------------------------------------
;An 8080 routine for generating a CYCLIC-
;REDUNDANCY-CHECK. Character leaves that
;character in location REM. By Fred Gutman.
;From 'EDN' magazine, June 5, 1979 issue, page 84.
;
DIVP:
LHLD REM ;GET REMAINDER
MOV A,H
ANI 128 ;Q-BIT MASK
PUSH PSW ;SAVE STATUS
DAD H ;2 X R(X)
LDA MESS ;MESSAGE BIT IN LSB
ADD L
MOV L,A
POP PSW
JZ QB2 ;IF Q-BIT IS ZERO
;
QB:
MOV A,H
XRI 0A0H ;MS HALF OF GEN. POLY
MOV H,A
MOV A,L
XRI 97H ;LS HALF OF GEN. POLY
MOV L,A
;
QB2:
SHLD REM
RET
;--------------------------------------------
;
;Hex output
;
HEXO:
PUSH PSW ;SAVE FOR RIGHT DIGIT
RAR ;RIGHT..
RAR ;..JUSTIFY..
RAR ;..LEFT..
RA